import type { ApplicationInfo } from "@/core/application/application-info"
import { toState, fromState } from "@/core/application/application-info"
import { WindowContext } from "@/core/window/window-context"
import type { ApplicationContext } from "@/core/application/application-context"

export class Application {
  readonly applicationContext: ApplicationContext
  readonly id: string

  readonly info: ApplicationInfo

  readonly windowContext: WindowContext

  constructor(info: ApplicationInfo, applicationContext: ApplicationContext) {
    this.id = info.id
    this.info = info
    this.windowContext = new WindowContext(this)
    this.applicationContext = applicationContext
  }

  open() {
    if (this.isOpened()) {
      this.active()
      return
    }
    if (typeof this.info.content.main === "string") {
      this.windowContext.createWindow(this.info.content.main)
    } else {
      this.info.content.main(this)
    }
    this.applicationContext.activeProcessor.active(this.id)
    //打开应用后的回调
    if (this.info.hook?.afterOpen) {
      this.info.hook.afterOpen(this)
    }
  }

  isOpened() {
    return this.windowContext.size() > 0
  }

  isActive() {
    return this.applicationContext.activeProcessor.isActive(this.id)
  }

  active() {
    this.applicationContext.activeProcessor.active(this.id)
  }

  zIndex() {
    return this.applicationContext.activeProcessor.getZIndex(this.id)
  }

  removeFromDock() {
    this.info.inDock = false
  }

  addInDock() {
    this.info.inDock = true
  }

  removeFromMainPanel() {
    this.info.inMainPanel = false
  }

  isHidden() {
    return this.windowContext.isHidden()
  }

  hide() {
    this.windowContext.hide()
  }

  show() {
    this.windowContext.show()
  }

  close() {
    if (this.info.hook?.beforeClose) {
      this.info.hook.beforeClose(this)
    }
    this.windowContext.close()
  }

  public fromState(obj: any) {
    if (!obj) {
      return
    }
    fromState(obj, this.info)
    this.windowContext.fromState(obj.windowContext)
  }

  public toState(): any {
    const obj: any = {}
    obj.info = toState(this.info)
    obj.windowContext = this.windowContext.toState()
    return obj
  }
}
